﻿#include "h/ControlCAN.h"
#include "h/canlib.h"
#include "KvaserCAN.h"
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#include <time.h>
#include <windows.h>
#include <process.h>

#pragma comment(lib,"canlib32.lib")

// ------------------ 宏与全局变量 ------------------
#define KVASER_MAX_CHANEL 4
#define TimerFreq 10000

// 日志开关
#define ENABLE_LOG 0
#if ENABLE_LOG
#define LOG(fmt, ...) printf(fmt, __VA_ARGS__)
#else
#define LOG(...)
#endif

// 线程安全
CRITICAL_SECTION g_cs[KVASER_MAX_CHANEL];

KVASER_DEVICE KvaserDevice[KVASER_MAX_CHANEL];
int maxChannel = KVASER_MAX_CHANEL;
VCI_ERR_INFO mErrorInfo;
LARGE_INTEGER cupFreq;
LONGLONG freqValue = 0;
#ifdef _DEBUG

#define CLEAR_DATA(data,len,v) do{ data[--len] = v;} while(len>0)
#define SET_LIMIT_VALUE(v,min,max) do{if(v<min){v=min;}else if(v>max){v=max;}}while(0)

int main()
{
	DWORD ret;
	int channel = 0;

	// 打开设备
	ret = VCI_OpenDevice(VCI_USBCAN1, 0, 0);
	if (ret != STATUS_OK) {
		printf("Open device failed: %d\n", ret);
		return -1;
	}
	printf("Device opened.\n");

	// 初始化通道
	VCI_INIT_CONFIG config = { 0 };
	config.Timing0 = 0x00;
	config.Timing1 = 0x1C; // 250kbps
	config.Mode = 0;       // 正常模式

	ret = VCI_InitCAN(VCI_USBCAN1, 0, channel, &config);
	if (ret != STATUS_OK) {
		printf("Init CAN failed: %d\n", ret);
		VCI_CloseDevice(VCI_USBCAN1, 0);
		return -1;
	}
	printf("CAN initialized.\n");

	// 启动通道
	ret = VCI_StartCAN(VCI_USBCAN1, 0, channel);
	if (ret != STATUS_OK) {
		printf("Start CAN failed: %d\n", ret);
		VCI_CloseDevice(VCI_USBCAN1, 0);
		return -1;
	}
	printf("CAN started.\n");

	// 发送一帧
	VCI_CAN_OBJ tx = { 0 };
	tx.ID = 0x123;
	tx.DataLen = 8;
	for (int i = 0; i < 8; ++i) tx.Data[i] = i;

	ULONG sent = VCI_Transmit(VCI_USBCAN1, 0, channel, &tx, 1);
	printf("Sent %lu frames.\n", sent);

	// 接收循环
	VCI_CAN_OBJ rx[32];
	while (true) {
		ULONG count = VCI_GetReceiveNum(VCI_USBCAN1, 0, channel);
		if (count > 0) {
			ULONG received = VCI_Receive(VCI_USBCAN1, 0, channel, rx, 32, 100);
			for (ULONG i = 0; i < received; ++i) {
				printf("RX: ID=0x%03X DLC=%d Data=", rx[i].ID, rx[i].DataLen);
				for (int j = 0; j < rx[i].DataLen; ++j)
					printf("%02X ", rx[i].Data[j]);
				printf("TS=%u\n", rx[i].TimeStamp);
			}
		}
		else {
			Sleep(100); // 避免 CPU 100%
		}
	}

	// 关闭设备
	VCI_CloseDevice(VCI_USBCAN1, 0);
	printf("Device closed.\n");
	return 0;
}
#endif

// ------------------ 初始化 ------------------
void VCI_InitializeComponent(int device = -1)
{
	if (device >= 0 && device < KVASER_MAX_CHANEL)
	{
		memset(&KvaserDevice[device], 0, sizeof(KvaserDevice[device]));
		KvaserDevice[device].Handle = canINVALID_HANDLE;
	}
	else
	{
		memset(&mErrorInfo, 0, sizeof(mErrorInfo));
		memset(KvaserDevice, 0, sizeof(KvaserDevice));
		for (int i = 0; i < KVASER_MAX_CHANEL; ++i)
		{
			InitializeCriticalSection(&g_cs[i]);
		}
	}
}

// ------------------ 错误码映射 ------------------
DWORD VCI_ChangeErrorCodeValue(canStatus errCode, int index = -1) 
{
	DWORD retCode = STATUS_ERR;
	PVCI_ERR_INFO pInfo = &mErrorInfo;
	if (index >= 0 && index < KVASER_MAX_CHANEL) 
	{
		pInfo = &KvaserDevice[index].ErrorInfo;
	}
	memset(pInfo, 0, sizeof(*pInfo));

	switch (errCode) 
	{
	case canOK: retCode = STATUS_OK; break;
	case canERR_NOTFOUND:
	case canERR_NOTINITIALIZED:
	case canERR_NOCHANNELS:
		pInfo->ErrCode |= ERR_DEVICENOTEXIST; break;
	case canERR_DYNALOAD:
	case canERR_DYNALIB:
	case canERR_DYNAINIT:
		pInfo->ErrCode |= ERR_LOADKERNELDLL; break;
	case canERR_HARDWARE:
	case canERR_NOT_SUPPORTED:
	case canERR_DRIVER:
	case canERR_INVHANDLE:
		pInfo->ErrCode |= ERR_DEVICEOPEN; break;
	case canERR_TXBUFOFL:
		pInfo->ErrCode |= ERR_BUFFEROVERFLOW; break;
	default:
		pInfo->ErrCode |= ERR_CMDFAILED; break;
	}
	return retCode;
}

// ------------------ 打开设备 ------------------
/**
 * @brief 打开指定类型的CAN设备。
 *
 * @param DeviceType 设备类型，如VCI_USBCAN1、VCI_USBCAN2等。
 * @param DeviceInd 设备索引，通常为0。
 * @param Reserved 保留参数，通常为0。
 * @return 返回设备打开状态，STATUS_OK表示成功，其他值表示失败。
 */
EXTERNC DWORD __stdcall VCI_OpenDevice(DWORD DeviceType, DWORD DeviceInd, DWORD Reserved) 
{
	static BOOL bInit = FALSE;
	if (!bInit) 
	{
		QueryPerformanceFrequency(&cupFreq);
		freqValue = cupFreq.QuadPart / TimerFreq;
		bInit = TRUE;
	}

	if (DeviceType == KVASER_DEVICE_TYPE || DeviceType == KVASER_ADV_DEVICE_TYPE) 
	{
		VCI_InitializeComponent(-1);
		canInitializeLibrary();
		canStatus status = canGetNumberOfChannels(&maxChannel);
		return (status == canOK && maxChannel > 0) ? STATUS_OK : VCI_ChangeErrorCodeValue(status, -1);
	}
	return STATUS_ERR;
}

// ------------------ 关闭设备 ------------------
/**
 * @brief 关闭已打开的CAN设备。
 *
 * @param DeviceType 设备类型，如VCI_USBCAN1、VCI_USBCAN2等。
 * @param DeviceInd 设备索引，通常为0。
 * @return 返回设备关闭状态，STATUS_OK表示成功，其他值表示失败。
 */
EXTERNC DWORD __stdcall VCI_CloseDevice(DWORD DeviceType, DWORD DeviceInd) 
{
	if (DeviceType == KVASER_DEVICE_TYPE || DeviceType == KVASER_ADV_DEVICE_TYPE) 
	{
		for (int i = 0; i < KVASER_MAX_CHANEL; ++i)
		{
			EnterCriticalSection(&g_cs[i]);
			if (KvaserDevice[i].Handle != canINVALID_HANDLE) 
			{
				canClose(KvaserDevice[i].Handle);
				KvaserDevice[i].Handle = canINVALID_HANDLE;
			}
			LeaveCriticalSection(&g_cs[i]);
		}
		canUnloadLibrary();
		return STATUS_OK;
	}
	return STATUS_ERR;
}

// ------------------ 初始化通道 ------------------
/**
 * @brief 初始化CAN通道。
 *
 * @param DeviceType 设备类型，如VCI_USBCAN1、VCI_USBCAN2等。
 * @param DeviceInd 设备索引，通常为0。
 * @param CANInd CAN通道索引，通常为0。
 * @param pInitConfig 初始化配置参数。
 * @return 返回初始化状态，STATUS_OK表示成功，其他值表示失败。
 */
EXTERNC DWORD __stdcall VCI_InitCAN(DWORD DeviceType,
	DWORD DeviceInd,
	DWORD CANInd,
	PVCI_INIT_CONFIG pInitConfig)
{
	UINT scale = 100;
	BOOL isExt = FALSE;
	// 1. 参数合法性检查
	if ((DeviceType != KVASER_DEVICE_TYPE && DeviceType != KVASER_ADV_DEVICE_TYPE) ||
		CANInd >= maxChannel || CANInd < 0 || pInitConfig == NULL)
	{
		return STATUS_ERR;
	}

	EnterCriticalSection(&g_cs[CANInd]);
	VCI_InitializeComponent(CANInd);
	P_KVASER_DEVICE device = &KvaserDevice[CANInd];

	// 备份配置（可选）
	memcpy(&device->Config, pInitConfig, sizeof(device->Config));

	// 2. 打开通道
	device->Handle = canOpenChannel(CANInd, canOPEN_ACCEPT_VIRTUAL);
	if (device->Handle == canINVALID_HANDLE)
	{
		LeaveCriticalSection(&g_cs[CANInd]);
		return VCI_ChangeErrorCodeValue(canERR_INVHANDLE, CANInd);
	}

	// 3. 设置波特率（82C200 格式）
	canStatus status = canSetBusParamsC200(device->Handle,
		(BYTE)pInitConfig->Timing0,
		(BYTE)pInitConfig->Timing1);
	if (status != canOK) 
		goto fail;

	// 4. 设置输出模式（Mode 0=正常，1=静默）
	status = canSetBusOutputControl(device->Handle,
		(pInitConfig->Mode == 0) ? canDRIVER_NORMAL : canDRIVER_SILENT);
	if (status != canOK) 
		goto fail;

	// 5. 设置验收滤波（标准/扩展）
	isExt = (pInitConfig->Filter & 0x80) != 0; // 高 bit 表示扩展
	status = canSetAcceptanceFilter(device->Handle,
		pInitConfig->AccCode,
		pInitConfig->AccMask,
		isExt);
	if (status != canOK) 
		goto fail;

	// 6. 其它初始化
	canIoCtl(device->Handle, canIOCTL_SET_TIMER_SCALE, &scale, sizeof(scale));
	scale = 1;
	canIoCtl(device->Handle, canIOCTL_SET_REPORT_ACCESS_ERRORS, &scale, sizeof(scale));

	LeaveCriticalSection(&g_cs[CANInd]);
	return STATUS_OK;

fail:
	canClose(device->Handle);
	device->Handle = canINVALID_HANDLE;
	LeaveCriticalSection(&g_cs[CANInd]);
	return VCI_ChangeErrorCodeValue(status, CANInd);
}

// ------------------ 启动通道 ------------------
/**
 * @brief 启动CAN通道。
 *
 * @param DeviceType 设备类型，如VCI_USBCAN1、VCI_USBCAN2等。
 * @param DeviceInd 设备索引，通常为0。
 * @param CANInd CAN通道索引，通常为0。
 * @return 返回启动状态，STATUS_OK表示成功，其他值表示失败。
 */
EXTERNC DWORD __stdcall VCI_StartCAN(DWORD DeviceType, DWORD DeviceInd, DWORD CANInd) 
{
	if (DeviceType != KVASER_DEVICE_TYPE && DeviceType != KVASER_ADV_DEVICE_TYPE) 
		return STATUS_ERR;
	if (CANInd >= maxChannel || KvaserDevice[CANInd].Handle == canINVALID_HANDLE) 
		return STATUS_ERR;

	EnterCriticalSection(&g_cs[CANInd]);
	KvaserDevice[CANInd].RxCount = 0;
	KvaserDevice[CANInd].ErrCount = 0;
	canStatus status = canBusOn(KvaserDevice[CANInd].Handle);
	LeaveCriticalSection(&g_cs[CANInd]);
	return VCI_ChangeErrorCodeValue(status, CANInd);
}

// ------------------ 复位通道 ------------------
EXTERNC DWORD __stdcall VCI_ResetCAN(DWORD DeviceType, DWORD DeviceInd, DWORD CANInd) 
{
	if (DeviceType != KVASER_DEVICE_TYPE && DeviceType != KVASER_ADV_DEVICE_TYPE) 
		return STATUS_ERR;
	if (CANInd >= maxChannel || KvaserDevice[CANInd].Handle == canINVALID_HANDLE) 
		return STATUS_ERR;

	EnterCriticalSection(&g_cs[CANInd]);
	canStatus status = canResetBus(KvaserDevice[CANInd].Handle);
	LeaveCriticalSection(&g_cs[CANInd]);
	return VCI_ChangeErrorCodeValue(status, CANInd);
}

// ------------------ 清空缓冲区 ------------------
EXTERNC DWORD __stdcall VCI_ClearBuffer(DWORD DeviceType, DWORD DeviceInd, DWORD CANInd) 
{
	if (DeviceType != KVASER_DEVICE_TYPE && DeviceType != KVASER_ADV_DEVICE_TYPE)
		return STATUS_ERR;
	if (CANInd >= maxChannel || KvaserDevice[CANInd].Handle == canINVALID_HANDLE) 
		return STATUS_ERR;

	EnterCriticalSection(&g_cs[CANInd]);
	canFlushReceiveQueue(KvaserDevice[CANInd].Handle);
	canFlushTransmitQueue(KvaserDevice[CANInd].Handle);
	KvaserDevice[CANInd].RxCount = 0;
	KvaserDevice[CANInd].ErrCount = 0;
	LeaveCriticalSection(&g_cs[CANInd]);
	return STATUS_OK;
}

// ------------------ 获取接收数量 ------------------
EXTERNC ULONG __stdcall VCI_GetReceiveNum(DWORD DeviceType, DWORD DeviceInd, DWORD CANInd) 
{
	if (DeviceType != KVASER_DEVICE_TYPE && DeviceType != KVASER_ADV_DEVICE_TYPE) 
		return 0;
	if (CANInd >= maxChannel || KvaserDevice[CANInd].Handle == canINVALID_HANDLE) 
		return 0;

	ULONG rxLevel = 0;
	canIoCtl(KvaserDevice[CANInd].Handle, canIOCTL_GET_RX_BUFFER_LEVEL, &rxLevel, sizeof(rxLevel));
	return rxLevel;
}

// ------------------ 发送 ------------------
/**
 * @brief 发送CAN消息。
 *
 * @param DeviceType 设备类型，如VCI_USBCAN1、VCI_USBCAN2等。
 * @param DeviceInd 设备索引，通常为0。
 * @param CANInd CAN通道索引，通常为0。
 * @param pSend 要发送的CAN消息数组。
 * @param Len 消息数组的长度。
 * @return 返回实际发送的消息数量。
 */
EXTERNC ULONG __stdcall VCI_Transmit(DWORD DeviceType, DWORD DeviceInd, DWORD CANInd, PVCI_CAN_OBJ pSend, ULONG Len) {
	if (DeviceType != KVASER_DEVICE_TYPE && DeviceType != KVASER_ADV_DEVICE_TYPE) return 0;
	if (CANInd >= maxChannel || !pSend || KvaserDevice[CANInd].Handle == canINVALID_HANDLE) return 0;

	EnterCriticalSection(&g_cs[CANInd]);
	ULONG sent = 0;
	for (ULONG i = 0; i < Len; ++i) {
		PVCI_CAN_OBJ obj = &pSend[i];
		unsigned int flags = canMSG_TXACK | canMSG_TXRQ;
		if (obj->ExternFlag) flags |= canMSG_EXT;
		if (obj->RemoteFlag) flags |= canMSG_RTR;

		canStatus status = canWrite(KvaserDevice[CANInd].Handle, obj->ID, obj->Data, obj->DataLen, flags);
		if (status != canOK) break;
		++sent;
	}
	LeaveCriticalSection(&g_cs[CANInd]);
	return sent;
}

// ------------------ 接收 ------------------
/**
 * @brief 接收CAN消息。
 *
 * @param DeviceType 设备类型，如VCI_USBCAN1、VCI_USBCAN2等。
 * @param DeviceInd 设备索引，通常为0。
 * @param CANInd CAN通道索引，通常为0。
 * @param pReceive 接收的CAN消息数组。
 * @param Len 消息数组的长度。
 * @param WaitTime 接收等待时间，单位毫秒。
 * @return 返回实际接收的消息数量。
 */
EXTERNC ULONG __stdcall VCI_Receive(DWORD DeviceType, DWORD DeviceInd, DWORD CANInd, PVCI_CAN_OBJ pReceive, ULONG Len, INT WaitTime)
{
	if (DeviceType != KVASER_DEVICE_TYPE && DeviceType != KVASER_ADV_DEVICE_TYPE) 
		return 0;
	if (CANInd >= maxChannel || !pReceive || KvaserDevice[CANInd].Handle == canINVALID_HANDLE)
		return 0;

	EnterCriticalSection(&g_cs[CANInd]);
	ULONG received = 0;
	while (received < Len) 
	{
		long id;
		BYTE data[8];
		UINT dlc, flags;
		unsigned long time;
		canStatus status = (WaitTime >= 0)
			? canReadWait(KvaserDevice[CANInd].Handle, &id, data, &dlc, &flags, &time, WaitTime)
			: canRead(KvaserDevice[CANInd].Handle, &id, data, &dlc, &flags, &time);

		if (status != canOK) 
			break;

		PVCI_CAN_OBJ obj = &pReceive[received];
		obj->ID = id;
		obj->DataLen = (BYTE)dlc;
		memcpy(obj->Data, data, 8);
		obj->TimeStamp = time;
		obj->TimeFlag = 1;
		obj->ExternFlag = (flags & canMSG_EXT) ? 1 : 0;
		obj->RemoteFlag = (flags & canMSG_RTR) ? 1 : 0;
		++received;
	}
	LeaveCriticalSection(&g_cs[CANInd]);
	return received;
}

EXTERNC DWORD __stdcall VCI_ReadBoardInfo(DWORD DeviceType, DWORD DeviceInd, PVCI_BOARD_INFO pInfo)
{
	if ((DeviceType == KVASER_DEVICE_TYPE || DeviceType == KVASER_ADV_DEVICE_TYPE) && pInfo != NULL)
	{
		ULONG32 tmp;
		int channel = DeviceInd;
		canGetChannelData(channel, canCHANNELDATA_DEVDESCR_ASCII, pInfo->str_hw_Type, 40);
		LOG("str_hw_Type %s \n", pInfo->str_hw_Type);

		tmp = 0;
		canGetChannelData(channel, canCHANNELDATA_CARD_SERIAL_NO, &tmp, sizeof(tmp));
		LOG(pInfo->str_Serial_Num, "%ld", tmp);
		LOG(pInfo->str_Serial_Num, "%d", tmp);
		LOG("str_Serial_Num %s \n", pInfo->str_Serial_Num);

		canGetNumberOfChannels(&maxChannel);
		pInfo->can_Num = (byte)maxChannel;

		pInfo->dr_Version = canGetVersion();
		LOG("dr_Version %d \n", pInfo->dr_Version);

		tmp = 0;
		canGetChannelData(channel, canCHANNELDATA_CARD_HARDWARE_REV, &tmp, sizeof(tmp));
		pInfo->hw_Version = (tmp >> 8) & 0xFFFF;
		LOG("hw_Version %ld \n", pInfo->hw_Version);

		tmp = 0;
		canGetChannelData(channel, canCHANNELDATA_CARD_FIRMWARE_REV, &tmp, sizeof(tmp));
		pInfo->fw_Version = tmp & 0xFFFF;
		LOG("fw_Version %ld \n", pInfo->fw_Version);

		tmp = 0;
		canGetChannelData(channel, canCHANNELDATA_DLL_FILETYPE, &tmp, sizeof(tmp));
		pInfo->in_Version = tmp & 0xFFFF;
		LOG("in_Version %d \n", pInfo->in_Version);

		tmp = 0;
		canGetChannelData(channel, canCHANNELDATA_CARD_NUMBER, &tmp, sizeof(tmp));
		pInfo->irq_Num = (USHORT)tmp;
		LOG("irq_Num %d \n", pInfo->irq_Num);
		return STATUS_OK;
	}
	else
	{
		return STATUS_ERR;
	}
}

EXTERNC DWORD __stdcall VCI_ReadErrInfo(DWORD DeviceType, DWORD DeviceInd, DWORD CANInd, PVCI_ERR_INFO pErrInfo)
{
	if (DeviceType != KVASER_DEVICE_TYPE || CANInd >= maxChannel || CANInd < 0 || pErrInfo == NULL)
	{
		return STATUS_ERR;
	}

	P_KVASER_DEVICE device = &KvaserDevice[CANInd];
	if (device->Handle < 0)
	{
		return STATUS_ERR;
	}

	// 读取错误计数器
	unsigned int txErr = 0, rxErr = 0, ovErr = 0;
	canStatus status = canReadErrorCounters(device->Handle, &txErr, &rxErr, &ovErr);
	if (status != canOK)
	{
		return STATUS_ERR;
	}

	// 请求并读取状态标志
	status = canRequestChipStatus(device->Handle);
	if (status != canOK)
	{
		return STATUS_ERR;
	}

	unsigned long flag = 0;
	status = canReadStatus(device->Handle, &flag);
	if (status != canOK)
	{
		return STATUS_ERR;
	}

	// 解析状态标志并填充错误代码
	unsigned int errCode = 0;

	if (flag & canSTAT_ERROR_PASSIVE)
	{
		errCode |= ERR_CAN_PASSIVE;
	}
	if (flag & canSTAT_BUS_OFF)
	{
		errCode |= ERR_CAN_BUSOFF;
	}
	if (flag & canSTAT_ERROR_WARNING)
	{
		errCode |= ERR_CAN_ERRALARM;
	}
	if (flag & (canSTAT_TXERR | canSTAT_RXERR))
	{
		errCode |= ERR_CAN_BUSERR;
	}
	if (flag & canSTAT_HW_OVERRUN)
	{
		errCode |= ERR_CAN_OVERFLOW;
	}
	if (flag & canSTAT_SW_OVERRUN)
	{
		errCode |= ERR_BUFFEROVERFLOW;
	}

	// 填充错误信息结构体
	device->ErrorInfo.ErrCode = errCode;
	device->ErrorInfo.Passive_ErrData[0] = 0; // 可根据需要进一步细化
	device->ErrorInfo.Passive_ErrData[1] = (BYTE)rxErr;
	device->ErrorInfo.Passive_ErrData[2] = (BYTE)txErr;
	device->ErrorInfo.ArLost_ErrData = (BYTE)ovErr;

	// 复制到用户提供的结构体
	memcpy(pErrInfo, &(device->ErrorInfo), sizeof(device->ErrorInfo));

	// 清空设备错误信息
	memset(&device->ErrorInfo, 0, sizeof(device->ErrorInfo));

	return STATUS_OK;
}
EXTERNC DWORD __stdcall VCI_ReadCANStatus(DWORD DeviceType, DWORD DeviceInd, DWORD CANInd, PVCI_CAN_STATUS pCANStatus)
{
	if ((DeviceType == KVASER_DEVICE_TYPE || DeviceType == KVASER_ADV_DEVICE_TYPE) && CANInd < maxChannel && CANInd >= 0)
	{
		P_KVASER_DEVICE device = &KvaserDevice[CANInd];
		if (device->Handle >= NULL && pCANStatus != NULL)
		{
			memset(pCANStatus, 0, sizeof(*pCANStatus));
			unsigned int txErr = 0, rxErr = 0, ovErr = 0;
			canStatus status = canReadErrorCounters(device->Handle, &txErr, &rxErr, &ovErr);
			if (status != canOK)
			{
				return STATUS_ERR;
			}
			pCANStatus->regTECounter = (UCHAR)txErr;
			pCANStatus->regRECounter = (UCHAR)rxErr;
			pCANStatus->ErrInterrupt = (UCHAR)(ovErr & 0xFF);
			pCANStatus->regEWLimit = 96;
			
			unsigned  long flag = 0;
			status = canReadStatus(device->Handle, &flag);
			return STATUS_OK;
		}
		else
		{
			return STATUS_ERR;
		}
	}
	else
	{
		return STATUS_ERR;
	}
}

EXTERNC DWORD __stdcall VCI_GetReference(DWORD DeviceType, DWORD DeviceInd, DWORD CANInd, DWORD RefType, PVOID pData)
{
	printf("VCI_GetReference\r\n");


	return STATUS_OK;
}

EXTERNC DWORD __stdcall VCI_SetReference(DWORD DeviceType, DWORD DeviceInd, DWORD CANInd, DWORD RefType, PVOID pData)
{

	printf("VCI_SetReference\r\n");

	return STATUS_OK;
}

#pragma endregion
#if 0
#pragma region ZLGCAN
DEVICE_HANDLE FUNC_CALL ZCAN_OpenDevice(UINT device_type, UINT device_index, UINT reserved)
{
	VCI_OpenDevice(device_type, device_index, reserved);
	return
}
UINT FUNC_CALL ZCAN_CloseDevice(DEVICE_HANDLE device_handle)
{
	return  VCI_CloseDevice(device_handle);
}
UINT FUNC_CALL ZCAN_GetDeviceInf(DEVICE_HANDLE device_handle, ZCAN_DEVICE_INFO* pInfo)
{

}

UINT FUNC_CALL ZCAN_IsDeviceOnLine(DEVICE_HANDLE device_handle)
{

}
EXTERNC CHANNEL_HANDLE FUNC_CALL ZCAN_InitCAN(DEVICE_HANDLE device_handle, UINT can_index, ZCAN_CHANNEL_INIT_CONFIG* pInitConfig)
{

}
EXTERNC UINT FUNC_CALL ZCAN_StartCAN(CHANNEL_HANDLE channel_handle)
{

}
EXTERNC UINT FUNC_CALL ZCAN_ResetCAN(CHANNEL_HANDLE channel_handle)
{

}
EXTERNC UINT FUNC_CALL ZCAN_ClearBuffer(CHANNEL_HANDLE channel_handle)
{

}
EXTERNC UINT FUNC_CALL ZCAN_ReadChannelErrInfo(CHANNEL_HANDLE channel_handle, ZCAN_CHANNEL_ERR_INFO* pErrInfo)
{

}
EXTERNC UINT FUNC_CALL ZCAN_ReadChannelStatus(CHANNEL_HANDLE channel_handle, ZCAN_CHANNEL_STATUS* pCANStatus)
{

}
EXTERNC UINT FUNC_CALL ZCAN_GetReceiveNum(CHANNEL_HANDLE channel_handle, BYTE type)
{

}
EXTERNC UINT FUNC_CALL ZCAN_Transmit(CHANNEL_HANDLE channel_handle, ZCAN_Transmit_Data* pTransmit, UINT len)
{

}
EXTERNC UINT FUNC_CALL ZCAN_Receive(CHANNEL_HANDLE channel_handle, ZCAN_Receive_Data* pReceive, UINT len, int wait_time)
{

}
EXTERNC UINT FUNC_CALL ZCAN_TransmitFD(CHANNEL_HANDLE channel_handle, ZCAN_TransmitFD_Data* pTransmit, UINT len)
{

}
EXTERNC UINT FUNC_CALL ZCAN_ReceiveFD(CHANNEL_HANDLE channel_handle, ZCAN_ReceiveFD_Data* pReceive, UINT len, int wait_time)
{

}

EXTERNC UINT FUNC_CALL ZCAN_TransmitData(DEVICE_HANDLE device_handle, ZCANDataObj* pTransmit, UINT len)
{

}
EXTERNC UINT FUNC_CALL ZCAN_ReceiveData(DEVICE_HANDLE device_handle, ZCANDataObj* pReceive, UINT len, int wait_time)
{

}
EXTERNC UINT FUNC_CALL ZCAN_SetValue(DEVICE_HANDLE device_handle, const char* path, const void* value)
{

}
EXTERNC const void* FUNC_CALL ZCAN_GetValue(DEVICE_HANDLE device_handle, const char* path)
{

}

EXTERNC IProperty* FUNC_CALL GetIProperty(DEVICE_HANDLE device_handle)
{

}
EXTERNC UINT FUNC_CALL ReleaseIProperty(IProperty* pIProperty)
{

}

#pragma endregion

#endif